#include "include.h"

#if FUNC_MUSIC_EN
extern u8 fname_buf[100];
#define IsUpper(c)  (((c)>='A')&&((c)<='Z'))
#define IsLower(c)  (((c)>='a')&&((c)<='z'))

//#define MUSIC_EXT_NUM 6                         //一共搜索3个扩展名
//const char tbl_music_ext[MUSIC_EXT_NUM][4] = {"mp3", "wav", "wma", "ape", "fla", "sbc"};

//转换为小写字符
AT(.text.fs.scan)
unsigned char char_tolower(unsigned char c)
{
	if (c >= 'A' && c <= 'Z') {
		c -= 'A'-'a';
	}
	return c;
}

//将字符串转换为小写
AT(.text.fs.scan)
void str_tolower(char *str, uint len)
{
    uint i;
    for (i = 0; i < len; i++) {
        str[i] = char_tolower(str[i]);
    }
}

AT(.text.fs.scan)
static bool file_is_music(char *ext_name)
{
//    u8 i;
//    for (i=0; i != MUSIC_EXT_NUM; i++) {
//        if (0 == memcmp(ext_name, (char *)(tbl_music_ext[i]), 3)) {
//            return true;
//        }
//    }
//    return false;

    if (0 == memcmp(ext_name, "mp3", 3)) {
        return true;
    }
#if MUSIC_WAV_SUPPORT
    if (xcfg_cb.music_wav_support) {
        if (0 == memcmp(ext_name, "wav", 3)) {
            return true;
        }
    }
#endif // MUSIC_WAV_SUPPORT

#if MUSIC_WMA_SUPPORT
    if (xcfg_cb.music_wma_support) {
        if (0 == memcmp(ext_name, "wma", 3)) {
            return true;
        }
    }
#endif // MUSIC_WMA_SUPPORT

#if MUSIC_APE_SUPPORT
    if (xcfg_cb.music_ape_support) {
        if (0 == memcmp(ext_name, "ape", 3)) {
            return true;
        }
    }
#endif // MUSIC_APE_SUPPORT

#if MUSIC_FLAC_SUPPORT
    if (xcfg_cb.music_flac_support) {
        if (0 == memcmp(ext_name, "fla", 3)) {
            return true;
        }
    }
#endif // MUSIC_FLAC_SUPPORT

#if MUSIC_SBC_SUPPORT
    if (0 == memcmp(ext_name, "sbc", 3)) {
        return true;
    }
#endif // MUSIC_SBC_SUPPORT
    return false;
}

///返回值： 0->不匹配的文件类型， 1->匹配的文件类型
AT(.text.fs.scan)
u8 music_file_filter(void)
{
    char extension[3];
    fs_get_fname_extension(extension);
    str_tolower(extension, 3);
    if (file_is_music(extension)) {
#if REC_FAST_PLAY
        bsp_update_final_rec_file_num();
#endif // REC_FAST_PLAY
        return 1;
    }
    return 0;
}

///返回值： 0->不匹配的目录类型， 1->匹配的目录类型
AT(.text.fs.scan)
u8 music_dir_filter(void)
{
#if REC_FAST_PLAY
    char sfn[13];
    fs_get_short_fname(sfn, 1);

    //录音目录
    if (is_record_dir(sfn)) {
        if (f_msc.rec_scan & BIT(0)) {
            f_msc.rec_scan |= BIT(1);
        }
    } else {
        f_msc.rec_scan &= ~BIT(1);
    }
#endif // REC_FAST_PLAY

    return 1;
}

#if MUSIC_REC_FILE_FILTER
///只播放录音文件歌曲
u8 music_only_record_dir_filter(void)
{
    char sfn[13];
    fs_get_short_fname(sfn, 1);

    //录音目录
    if (is_record_dir(sfn)) {
#if REC_FAST_PLAY
        if (f_msc.rec_scan & BIT(0)) {
            f_msc.rec_scan |= BIT(1);
        }
#endif // REC_FAST_PLAY
        return 1;
    }
    return 0;
}

///只播放录音文件歌曲
u8 music_only_record_file_filter(void)
{
    char extension[3];
    fs_get_fname_extension(extension);
    str_tolower(extension, 3);
    if (file_is_music(extension) && fs_get_dir_depth()) {   //去掉根目录正常歌曲
#if REC_FAST_PLAY
        bsp_update_final_rec_file_num();
#endif // REC_FAST_PLAY
        return 1;
    }
    return 0;
}

///去掉录音文件
u8 music_rm_record_dir_filter(void)
{
    char sfn[13];
    fs_get_short_fname(sfn, 1);

    //录音目录
    if (is_record_dir(sfn)) {
        return 0;
    }

    return 1;
}
#endif // MUSIC_REC_FILE_FILTER

#if REC_FAST_PLAY
void bsp_update_final_rec_file_num(void)
{
    if (fs_get_dir_depth() && (f_msc.rec_scan & BIT(1))) {
        if (fs_get_ftime() > sys_cb.ftime) {
            sys_cb.ftime = fs_get_ftime();
            sys_cb.rec_num = fs_get_file_count();
        }
    }
}
#endif // REC_FAST_PLAY

AT(.text.stream)
int stream_read(void *buf, unsigned int size)
{
    UINT len;
    u8 res = fs_read(buf, size, &len);
    if (res == FR_OK) {
#if MUSIC_ENCRYPT_EN
        if (f_msc.encrypt) {
            music_stream_decrypt(buf, len);
        }
#endif
        return len;
    } else {
        return -1;
    }
}

AT(.text.stream)
bool stream_seek(unsigned int ofs, int whence)
{
#if MUSIC_ENCRYPT_EN
    if (f_msc.encrypt) {
        if (whence == SEEK_SET) {
            ofs += 1;
        }
    }
#endif
    u8 res = fs_lseek(ofs, whence);
    if (res == FR_OK) {
        return true;
    }
    return false;
}
#endif // FUNC_MUSIC_EN

#if 0       //删除文件夹及其子目录

///返回值： 0->不匹配的文件类型， 1->匹配的文件类型
AT(.text.fs.scan)
u8 test_file_filter(void)
{
    return 1;
}
///返回值： 0->不匹配的目录类型， 1->匹配的目录类型
AT(.text.fs.scan)
u8 test_dir_filter(void)
{
    return 1;
}

#define CLUST   DWORD
/* Directory object structure */
typedef struct {
    BYTE*   fn;             /* Pointer to the SFN (in/out) {file[8],ext[3],status[1]} */
    CLUST   sclust;         /* Table start cluster (0:Static table) */
    CLUST   clust;          /* Current cluster */
    DWORD   sect;           /* Current sector */
    DWORD   index;          /* Current read/write index number */
    BYTE*	dir;	        /* Pointer to the directory item in the win[] */
} DIR;
bool dir_delete_en = false;
bool scan_delete_en = false;
bool delete_scan_en(void)      //循环扫描删除，需要使能此函数
{
    return scan_delete_en;
}
bool delete_dir_en(void)      //开始删除文件夹
{
    return dir_delete_en;
}
//-->delete
typedef struct {
    DIR dir_save;               //目录项保存使用
    char dir_name_save[13];     //exfat需要大小写转换，保存名字用到
} delete_save_t;
delete_save_t delete_save[8]; //支持的最大目录深度是8

u16 fs_get_delete_files(char *path, u8 len, delete_save_t *dir_save);
bool fs_delete_file(u32 file_num, char *path, u8 len, delete_save_t *dir_save);
u8 fs_delete_folder(char *path, u8 len, delete_save_t *dir_save)
{
    /*
        path:需要删除的文件夹名字
        len:文件夹名字长度
        dir_save:内部保存文件目录使用

        删除整个文件夹包含其子目录，暂时只支持单独名字的文件夹，不支持同名文件夹的情况
        只支持短文件名
        例如fs_delete_folder("DIR_0_1", 7, delete_save);
    */
    fs_scan_set(SCAN_SPEED|SCAN_SUB_FOLDER, test_file_filter, test_dir_filter);     //删除的话需要先删除所有格式类型的文件

    scan_delete_en = true;
    u32 file_total_1 = fs_get_delete_files(path, len, dir_save);                    //获取目录下所有文件总数
    my_printf("--->file_total_1:%d\n", file_total_1);

    for (u16 i = 1; i <= file_total_1; i++) {
        my_printf("file:%d, delete:%d\n", i, fs_delete_file(1, path, len, dir_save));         //循环扫描删除目录下的所有文件
        fs_get_delete_files(path, len, dir_save);
    }
    scan_delete_en = false;
    dir_delete_en = true;
    fs_get_delete_files(path, len, dir_save);                 //再次扫描，此时文件夹都是空的，直接删除目录下所有文件夹
    dir_delete_en = false;

    return true;
}
/*
eg:

    fsdisk_callback_init(sys_cb.cur_dev);
    if (!fs_mount()) {
        my_printf("--->mount_error\n");
    }
    fs_delete_folder("DIR_1", 5, delete_save);

*/
void fs_dl_fd(void)
{
    fs_delete_folder("DIR_0_1", 5, delete_save);
}
#endif

#if FUNC_MUSIC_EN
AT(.text.fs.rename)
void unicode_to_ascii(char *dest, char *source, u8 CpySize)
{
    for(u32 i = 0; i < CpySize; i++){
        dest[i] = source[i*2];
    }
}

AT(.text.fs.rename)
void ascii_to_unicode(char *uni_ptr, char *sfn_ptr, u8 CpySize)
{
    for (u8 i = 0; i < CpySize; i++) {
        uni_ptr[i*2] = sfn_ptr[i];
    }
}

AT(.text.fs.rename)
void filename_convert_upper(char *inbuf,  u16 buf_len)
{//短文件名判断需要全部都是大写字母,包括后缀名
    char tempBuf[100];
    memset(tempBuf, 0, sizeof(tempBuf));
    memcpy(tempBuf, inbuf, buf_len);
    for(u8 i = 0; i < buf_len; i++){
        if((tempBuf[i] != 0) && (tempBuf[i] != ' ')){
            if(IsLower(tempBuf[i])){
                *inbuf++ = tempBuf[i] - 0x20;
            }else{
                *inbuf++ = tempBuf[i];
            }
        }
    }
}

AT(.text.fs.rename)
void filename_dirname_link(
    char *infilename,
    u8 infilename_len,
    u8 file_LSFN_sta,   /*0-infilename is unicode, else is ascii*/

    char *indirname,
    u8 indirname_len,
    u8 dir_LSFN_sta,    /*0-indirname is unicode, else is ascii*/

    char *outfullname,  /*return ascii*/
    u8 outfullname_len
)
{
    u8 name_len = 0;
    char *outfullname_ptr = outfullname;
    memset(outfullname, 0, outfullname_len);

    if(*indirname != 0){//sub
        if(dir_LSFN_sta == 0){//获取到长文件夹名
        unicode_to_ascii(outfullname, indirname, indirname_len);
        while(*outfullname_ptr != 0xFF){//指向第1个ff
            outfullname_ptr++;
            name_len++;
        }
        *(outfullname_ptr - 1) = '/';
        memset(outfullname_ptr, 0, (outfullname_len- name_len));
        }else{//获取到短文件夹名
            memcpy(outfullname, indirname, indirname_len);
            outfullname_ptr += indirname_len;
            *outfullname_ptr = '/';
            outfullname_ptr++;
            name_len += (indirname_len + 1);
        }
    }else{//root

    }

    if(file_LSFN_sta == 0){//获取到长文件名
        unicode_to_ascii(outfullname_ptr, infilename, infilename_len);
    }else{//获取到短文件夹名
        memcpy(outfullname_ptr, infilename, infilename_len);
    }
    name_len += infilename_len;
    outfullname[outfullname_len - 2] = name_len;
}


//测试pf_rename代码
#define RENAME_ROOT_OR_SUB  1
AT(.text.fs.rename)
void pf_rename_test_proc()
{
    static u8 file_LSFN_sta = 0;//0-获取到长文件名,1-获取到短文件名
    static u8 name_num = 0x31;

    char dir_path_buf[100];
    static u8 dir_LSFN_sta = 0;

    char oldname_path[100];
    u16 oldname_path_len;
    char oldname_buf[102];

    char frename_buf[102];
    u16 frename_path_len;
    u16 frename_file_len;

#if RENAME_ROOT_OR_SUB
    char frename_path[] = "F1/1aB.mp3";
    //char frename_path[] = "F1ABCDEFGHMN12/3aB.mp3";
    //char frename_dir[] = "F1ABCDEFGHMN12/";
    char frename_file[] = "1aB.mp3";

    //char frename_path2[]= "F1/1zxc.mp3";
#else
    char frename_path[] = "1aB.mp3";
    char frename_file[] = "1aB.mp3";
#endif
    memset(f_msc.fname, 0, sizeof(fname_buf));
    memset(dir_path_buf, 0, sizeof(dir_path_buf));
    fs_get_dirname_for_number(2, 1, dir_path_buf, sizeof(dir_path_buf), &dir_LSFN_sta);
    printf("dir_path_buf :\n");
    print_r(dir_path_buf, 100);

    fs_get_filename_for_number(2, 1, f_msc.fname, sizeof(fname_buf), &file_LSFN_sta);//修改当前的文件名字
    printf("music_lfn_name :\n");
    print_r(f_msc.fname, 100);

    if(file_LSFN_sta == 0){
        memset(oldname_buf, 0, sizeof(oldname_buf));
        oldname_path_len = (f_msc.fname[98]);
        oldname_buf[0] = oldname_path_len & 0x0F;
        oldname_buf[1] = oldname_path_len >> 8;
        memcpy(&oldname_buf[2], f_msc.fname, 100);
    }else{
        oldname_path_len = (f_msc.fname[98]);
    }

    printf("file_LSFN_sta: %d\n", file_LSFN_sta);
    printf("dir_LSFN_sta: %d\n", dir_LSFN_sta);
    filename_dirname_link(
        f_msc.fname,
        f_msc.fname[98],
        file_LSFN_sta,
        dir_path_buf,
        dir_path_buf[98],
        dir_LSFN_sta,
        oldname_path,
        100);
    printf("Name Link_oldname_path:\n");
    print_r(oldname_path, 100);

    if(file_LSFN_sta == 0){//长文件名
        printf("!!! long file name !!!\n");
    }else{//短文件名
        printf("!!! short file name !!!\n");
        // filename_convert_upper(f_msc.fname, f_msc.fname[98]);
        // printf("music_lfn_name upper :\n");
        // print_r(f_msc.fname, 100);

        memset(oldname_buf, 0, sizeof(oldname_buf));
        ascii_to_unicode(oldname_buf, f_msc.fname, oldname_path_len);
    }

    printf("oldname_buf :\n");
    print_r(oldname_buf, 100);

    #if RENAME_ROOT_OR_SUB
        frename_path[3] = name_num;
        frename_file[0] = name_num++;
        if(name_num >= 0x39){
            name_num = 0x31;
        }
    #else
        frename_path[0] = name_num;
        frename_file[0] = name_num++;
        if(name_num >= 0x39){
            name_num = 0x31;
        }
    #endif

    memset(frename_buf, 0, sizeof(frename_buf));
    frename_path_len = (sizeof(frename_path)/(sizeof(char))) - 1;//减去'\0'
    frename_file_len = (sizeof(frename_file)/(sizeof(char))) - 1;

    printf("frename_path 8 :\n");
    print_r(frename_path, frename_path_len);

    frename_buf[0] = frename_file_len  & 0x0F;
    frename_buf[1] = frename_file_len>> 8;
    ascii_to_unicode(&frename_buf[2], frename_file, frename_file_len);
    printf("frename_buf:\n");
    print_r(frename_buf, frename_file_len * 2 + 2);

    fs_rename(oldname_path, frename_path, oldname_buf, frename_buf);
    f_msc.file_total = fs_get_total_files();//改名字后，刷新下文件的序号
    f_msc.dir_total = fs_get_dirs_count();
}
#endif
